package com.kakarote.hrm.controller;


import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kakarote.common.log.annotation.OperateLog;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.entity.OperationResult;
import com.kakarote.common.log.enums.ApplyEnum;
import com.kakarote.common.log.enums.BehaviorEnum;
import com.kakarote.common.log.enums.OperateObjectEnum;
import com.kakarote.common.log.enums.OperateTypeEnum;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.enums.SystemCodeEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.entity.UploadEntity;
import com.kakarote.hrm.entity.BO.*;
import com.kakarote.hrm.entity.PO.HrmDept;
import com.kakarote.hrm.entity.VO.DeptEmployeeDataTotalVO;
import com.kakarote.hrm.entity.VO.DeptVO;
import com.kakarote.hrm.entity.VO.QueryEmployeeListByDeptIdVO;
import com.kakarote.hrm.service.IHrmDataPushLogService;
import com.kakarote.hrm.service.IHrmDeptService;
import com.kakarote.hrm.task.PushDataTask;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 部门表 前端控制器
 * </p>
 *
 * @author huangmingbo
 * @since 2020-05-12
 */
@RestController
@RequestMapping("/hrmDept")
@Api(tags = "组织管理-部门")
@Slf4j
public class HrmDeptController {

    @Autowired
    private IHrmDeptService deptService;
    @Autowired
    private PushDataTask pushDataTask;

    @PostMapping("/addDept")
    @ApiOperation("添加部门")
    public Result addDept(@Valid @RequestBody AddDeptBO addDeptBO) {
        deptService.addOrUpdate(addDeptBO);
        return Result.ok();
    }

    @GetMapping("/updateComprehensiveDept")
    @ApiOperation("修改直接挂在机构下面的人员")
    public Result updateComprehensiveDept() {
        deptService.updateComprehensiveDept();
        return Result.ok();
    }

    @PostMapping("/setDept")
    @ApiOperation("修改部门")
    public Result setDept(@Valid @RequestBody AddDeptBO addDeptBO) {
        deptService.addOrUpdate(addDeptBO);
        return Result.ok();
    }

    @PostMapping("/employeeDataTotal")
    @ApiOperation("员工数据统计")
    public Result<List<DeptEmployeeDataTotalVO>> employeeDataTotal(@RequestBody DeptEmployeeDataTotalVO dataTotalVO) {
        return Result.ok(deptService.employeeDataTotal(dataTotalVO));
    }

    @PostMapping("/queryById/{deptId}")
    @ApiOperation("查询部门详情")
    public Result<DeptVO> queryById(@PathVariable("deptId") Long deptId) {
        DeptVO deptVO = deptService.queryById(deptId);
        return Result.ok(deptVO);
    }

    @PostMapping("/queryTreeList")
    @ApiOperation("查询部门列表")
    public Result<List<DeptVO>> queryTreeList(@RequestBody QueryDeptListBO queryDeptListBO) {
        List<DeptVO> treeNode = deptService.queryTreeList(queryDeptListBO);
        return Result.ok(treeNode);
    }

    @PostMapping("/queryDeptNameMap")
    @ApiOperation("查询部门名称Map")
    public Result<Map<Long, String>> queryDeptNameMap() {
        Map<Long, String> deptMap = deptService.getAllDeptPath();
        return Result.ok(deptMap);
    }

    @PostMapping("/queryEmployeeByDeptId")
    @ApiOperation("通过部门id查询员工列表")
    public Result<BasePage<QueryEmployeeListByDeptIdVO>> queryEmployeeByDeptId(@RequestBody QueryEmployeeByDeptIdBO employeeByDeptIdBO) {
        BasePage<QueryEmployeeListByDeptIdVO> page = deptService.queryEmployeeByDeptId(employeeByDeptIdBO);
        return Result.ok(page);
    }

    @PostMapping("/queryManageEmployeeByDeptId")
    @ApiOperation("组织负责人、分管领导列表")
    public Result<List<QueryEmployeeListByDeptIdVO>> queryManageEmployeeByDeptId(@RequestBody QueryEmployeeByDeptIdBO employeeByDeptIdBO) {
        if (employeeByDeptIdBO.getDeptId() == null){
            return Result.ok(ListUtil.empty());
        }
        List<QueryEmployeeListByDeptIdVO> empList = deptService.queryManageEmployeeByDeptId(employeeByDeptIdBO);
        return Result.ok(empList);
    }


    @PostMapping("/deleteDeptById/{deptId}")
    @ApiOperation("删除部门")
    public Result deleteDeptById(@PathVariable("deptId") String deptId) {
        deptService.deleteDeptById(deptId);
        return Result.ok();
    }

    @PostMapping("/deptMove")
    @ApiOperation("部门拖拽")
    public Result deptMove(@Valid @RequestBody DeptMoveBO deptMoveBO) {
        deptService.deptMove(deptMoveBO);
        return Result.ok();
    }

    @GetMapping("/childrenCount/{deptId}")
    @ApiOperation("子级部门统计")
    public Result deptChildrenCount(@PathVariable("deptId") Long deptId) {
        QueryWrapper<HrmDept> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id",deptId);
        return Result.ok(deptService.count(wrapper));
    }

    @GetMapping("/dataSync")
    @ApiOperation("数据同步")
    public Result deptDataSync() {
        pushDataTask.pushDept("手动同步部门数据");
        return Result.ok();
    }

    @PostMapping("/pushData")
    @ApiOperation("部门数据同步")
    public Result pushEmployeeData(@RequestBody List<Long> deptIds) {
        if (deptIds.isEmpty()){
            return Result.error(SystemCodeEnum.SYSTEM_ERROR,"请选择部门");
        }
        int i = deptService.pushDeptData(deptIds);
        if (i > 0) {
            return Result.ok();
        } else {
            return Result.error(SystemCodeEnum.SYSTEM_ERROR,"数据同步失败");
        }
    }



    @GetMapping("/exportDeptList")
    @ApiOperation("导出部门公司列表")
    public Result exportDeptList() {
        return Result.ok(deptService.exportDeptList());
    }

    @PostMapping("/export")
    @ApiOperation("导出部门")
    public void export(HttpServletResponse response,@RequestBody DeptVO deptVO) throws IOException {
        deptService.exportExcel(response,deptVO.getDeptIdList());
    }

    @PostMapping("/downloadExcel")
    @ApiOperation("获取导入模板")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        deptService.downloadExcel(response);
    }

    @PostMapping("/excelImport")
    @ApiOperation("excel导入部门")
    @OperateLog(apply = ApplyEnum.HRM, behavior = BehaviorEnum.EXCEL_IMPORT, type = OperateTypeEnum.IMPORT, object = OperateObjectEnum.HRM_DEPT)
    public Result<JSONObject> excelImport(@RequestParam("file") MultipartFile file) {
        JSONObject object = deptService.excelImport(file);

        UploadEntity uploadEntity = deptService.uploadTempFile(file, null);

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject("uploadData", uploadEntity.getFileId());
        operationLog.setOperationObject("name", "部门");

        JSONObject info = new JSONObject();
        info.put("count", object.getInteger("totalSize"));
        info.put("errorSize", object.getInteger("errSize"));
        info.put("errorFile", object.getString("token"));
        operationLog.setOperationInfo(info.toJSONString());
        return OperationResult.ok(object, ListUtil.toList(operationLog));
    }

    @PostMapping("/downExcel")
    @ApiOperation("excel下载错误数据")
    public void downExcel(@RequestParam("token") String token, HttpServletResponse response) {
        String path = FileUtil.getTmpDirPath() + "/" + token;
        if (FileUtil.exist(path)) {
            File file = FileUtil.file(path);
            final String fileName = file.getName();
            final String contentType = ObjectUtil.defaultIfNull(FileUtil.getMimeType(fileName), "application/octet-stream");
            BufferedInputStream in = null;
            try {
                in = FileUtil.getInputStream(file);
                ServletUtil.write(response, in, contentType, "import_error.xls");
            } finally {
                IoUtil.close(in);
            }
            FileUtil.del(path);
        }
    }


}

